// Copyright (c) 2021 百小僧, Baiqian Co.,Ltd.
// Util is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2. 
// You may obtain a copy of Mulan PSL v2 at:
//             https://gitee.com/dotnetchina/Util/blob/master/LICENSE

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Terra.Core.Common.Utils;

/// <summary>
/// 字符串扩展
/// </summary>
public static class StringExtensions
{
    #region 空值判断

    /// <summary>
    /// 是否为空
    /// </summary>
    /// <param name="value">值</param>
    public static bool IsEmpty(this string value)
    {
        return string.IsNullOrWhiteSpace(value);
    }

    /// <summary>
    /// 判断字符串是否不为空
    /// </summary>
    /// <param name="value">值</param>
    public static bool IsNotEmpty(this string value)
    {
        return !string.IsNullOrWhiteSpace(value);
    }

    #endregion

    #region 常用判断

    /// <summary>
    /// 是否为电子邮件
    /// </summary>
    /// <param name="value">邮件地址</param>
    public static bool IsEmail(this string value)
    {
        const string pattern = @"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$";
        return value.IsNotEmpty() && Regex.IsMatch(value, pattern);
    }

    /// <summary>
    /// 是否为手机号码
    /// </summary>
    /// <param name="value">手机号码</param>
    public static bool IsMobile(this string value)
    {
        const string pattern = @"^1[3-9]\d{9}$";
        return value.IsNotEmpty() && Regex.IsMatch(value, pattern);
    }

    /// <summary>
    /// 是否为身份证号
    /// </summary>
    /// <param name="value">身份证号</param>
    public static bool IsIdCard(this string value)
    {
        const string pattern = @"^(\d{15}$|^\d{18}$|^\d{17}(\d|X|x))$";
        return value.IsNotEmpty() && Regex.IsMatch(value, pattern);
    }

    #endregion

    #region 格式化

    /// <summary>
    /// 转换为驼峰命名
    /// </summary>
    /// <param name="value">值</param>
    public static string ToCamelCase(this string value)
    {
        if (value.IsEmpty())
            return value;
        return char.ToLowerInvariant(value[0]) + value.Substring(1);
    }

    /// <summary>
    /// 转换为帕斯卡命名
    /// </summary>
    /// <param name="value">值</param>
    public static string ToPascalCase(this string value)
    {
        if (value.IsEmpty())
            return value;
        return char.ToUpperInvariant(value[0]) + value.Substring(1);
    }

    /// <summary>
    /// 转换为下划线分隔命名
    /// </summary>
    /// <param name="value">值</param>
    public static string ToSnakeCase(this string value)
    {
        if (value.IsEmpty())
            return value;
        return string.Concat(value.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower();
    }

    #endregion

    #region 截取和分割

    /// <summary>
    /// 安全截取字符串
    /// </summary>
    /// <param name="value">值</param>
    /// <param name="startIndex">起始位置</param>
    /// <param name="length">长度</param>
    public static string SafeSubstring(this string value, int startIndex, int length)
    {
        if (value.IsEmpty())
            return string.Empty;
        if (startIndex < 0)
            startIndex = 0;
        if (length < 0)
            length = 0;
        if (startIndex >= value.Length)
            return string.Empty;
        if (startIndex + length > value.Length)
            length = value.Length - startIndex;
        return value.Substring(startIndex, length);
    }

    /// <summary>
    /// 分割逗号分隔的字符串为字符串数组
    /// </summary>
    /// <param name="value">值</param>
    public static string[] SplitByComma(this string value)
    {
        return value.IsEmpty() ? Array.Empty<string>() : value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
    }

    #endregion

    #region 转换

    /// <summary>
    /// 转换为整型
    /// </summary>
    /// <param name="value">值</param>
    public static int ToInt(this string value)
    {
        return int.TryParse(value, out int result) ? result : 0;
    }

    /// <summary>
    /// 转换为可空整型
    /// </summary>
    /// <param name="value">值</param>
    public static int? ToIntOrNull(this string value)
    {
        return int.TryParse(value, out int result) ? result : null;
    }

    /// <summary>
    /// 转换为长整型
    /// </summary>
    /// <param name="value">值</param>
    public static long ToLong(this string value)
    {
        return long.TryParse(value, out long result) ? result : 0;
    }

    /// <summary>
    /// 转换为双精度浮点数
    /// </summary>
    /// <param name="value">值</param>
    public static double ToDouble(this string value)
    {
        return double.TryParse(value, out double result) ? result : 0;
    }

    /// <summary>
    /// 转换为布尔值
    /// </summary>
    /// <param name="value">值</param>
    public static bool ToBool(this string value)
    {
        return bool.TryParse(value, out bool result) && result;
    }

    #endregion
}